package index;


import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.TreeMap;
import java.io.File;
import java.sql.SQLException;


import java.io.PrintWriter;
import java.io.IOException;















import org.jsoup.Jsoup;
//import org.w3c.dom.*;
//import org.xml.sax.*;

//import javax.xml.parsers.*;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import utils.FileList;
import store.BaseWriter;


/**
  * IndexWriter ecrit l'index (c'est a dire les 3 tables de la BD). Les documents sont parses avec Jsoup.
  *
  */

public final class IndexWriter {
  
		  
  
  /** Vecteur contenant des objets Document
  * @see DocumentAIndexer
  */
  public Vector documentVector;
  

  /** Vecteur contenant des objets Noeud
  * @see NodeAIndexer
  */
  public Vector pathTable;
  
  
  /** Hashtable contenant des objets Term 
  * @see Term
  */
  public Hashtable postingTable;

  
// compteur pour l'identifiant du terme  
protected int count_id_term;
// compteur pour l'identifiant de document
protected int count_id_doc;

// nombre de termes dans un document
protected int term_count;


protected BaseWriter maBase;

// liste des fichiers a indexer
protected Vector fileList;


public int mode = 0;


/**
* COnstructeur. Met les compteurs a zero et initialise les structures des stockage, instancie le parseur.
*/   
public IndexWriter(String direc, BaseWriter base) throws
IOException{

fileList = FileList.list(direc);
maBase= base;

documentVector=new Vector();
pathTable = new Vector();
postingTable = new Hashtable();

count_id_doc=0;
count_id_term=0;
term_count=0;
}  
  
  
  /**
  * Permet de remplir la base avec toutes les informations contenues dans la memoire
  */
  public  void construct() {
  
  
  for (int i=0; i<fileList.size();i++) {
  	String monNom = (String) fileList.elementAt(i);
  	
	System.out.println("traitement du fichier"+monNom);
	File fichier = new File(monNom);

	term_count=0;
	
	try {
		// parsage du fichier
		Document document = Jsoup.parse(fichier, "UTF-8");	
		
		//on recupère le texte contenu et on l'index
		
		//Ajout par JayJay
		//title
		String title = document.title();
		constructTerme(title, 1, count_id_doc); //On contruit la table terme
		
		//h1
		Elements h1  = document.select("h1");
		constructTerme (h1.text(), 2, count_id_doc);
	
		//h2
		Elements h2  = document.select("h2");
		constructTerme (h2.text(), 3, count_id_doc);
		
		//h3
		Elements h3  = document.select("h3");
		constructTerme (h3.text(), 4, count_id_doc);
		
		//meta
		Elements meta = document.getElementsByTag("meta");
		for (Element metaE : meta) {
			 
		  if (metaE.attr("name").equals("keywords")){
			  String keywords = metaE.attr("content");
			  constructTerme (keywords , 5, count_id_doc);
		  }
		  
		  if (metaE.attr("name").equals("description")){
			  String descript = metaE.attr("content");
			  constructTerme (descript , 6, count_id_doc);
		  }
		  
		  if (metaE.attr("name").equals("classification")){
			  String classif = metaE.attr("content");
			  constructTerme (classif , 7, count_id_doc);
		  }
		}
		
		//Img Alt
		Elements imgs = document.getElementsByTag("img");
		for (Element img : imgs) {
			  String imgAlt = img.attr("alt");
			  constructTerme (imgAlt , 8, count_id_doc);
		
			  String imgTitle = img.attr("title");
		     constructTerme (imgTitle , 9, count_id_doc);
		}
		
		
		//Caption (tableau)
		Elements caption = document.getElementsByTag("caption");
		constructTerme (caption.text() , 10, count_id_doc);
		
		//Tableau summary
		Elements tables = document.getElementsByTag("table");
		for (Element table : tables) {
					  String summary = table.attr("summary");
					  constructTerme (summary , 11, count_id_doc);
		}
		
		
		//Mot en gras
		Elements strong = document.getElementsByTag("strong");
		constructTerme (strong.text() , 12, count_id_doc);
		
		//Nom des liens a
		Elements a = document.getElementsByTag("img");
		for (Element aE : a) {
			  String aTitle = aE.attr("title");
			  constructTerme (aTitle , 13, count_id_doc);
		}
		
		
		//Body		
		Element body = document.body();
		//System.out.println("corps doc "+body.text());
	    constructTerme(body.text(), 0, count_id_doc); //On contruit la table terme
		}
		
	catch (IOException io){
		System.out.println("Erreur de d'entree/sortie");
		}
	DocumentAIndexer dtoindex= new DocumentAIndexer(count_id_doc, monNom);
	documentVector.add(dtoindex);
	count_id_doc++;
  }//on a fini de parcourir tous les documents

// on insere les donnees sur les documents dans la base
	try{
	//PrintDocumentTable();
	maBase.insertDocument(documentVector);
	}
	catch (SQLException sqle) {
		System.out.println("Erreur insertion document et noeuds "+sqle.getMessage());
	}

	
	// on insere les termes dans la base
try{
	//PrintPostingTable();
	maBase.insertPosting(postingTable);	
}
catch (SQLException sqle2) {
	//System.out.println("Erreur insertion termes "+sqle2.getMessage());
}  
  
  } // construct() 
  
  
  
  
  
  
  
  
 



/**
* Permet de remplir la table de posting avec le texte.
*/
//public final void constructTerme (String texte) {
public final void constructTerme (String texte, int idbalise, int iddoc) {

//Hashtable new_document= new Hashtable();
// il faut traiter tout ce texte...
		
	TextFilter filter = new TextFilter();

String[] mots = filter.filtreTerme(texte);

//Lemmatisation
if (mode == 2) {
try {
 mots = filter.lemmatiserTermes(mots);
} catch (Throwable e) {
// TODO Auto-generated catch block
	e.printStackTrace();
}
}


				
for (int j=0;j<mots.length; j++) {

	// on pourrair utiliser Porter ou la troncature ...!
	String mot=mots[j];
	
	
	// on verifie que le mot n'est pas un mot vide ou un mot qui contient un @ ou un %
	if (filter.testMotVide(mot)) {
		
		if (mode == 1) {
			//On peut faire la troncature ici
			mot = filter.troncTerme(mot);
		}
			
			TextObject myTermText = new TextObject(mot);
			term_count++;
		 if (postingTable.containsKey(myTermText)) { // si la table de posting contient deja le terme car rencontrer soit dans une autre doc, soit dans le même

                           Term myTerm=(Term) postingTable.get(myTermText); //on récupère les infos qu'on a jusqu'ici
                           postingTable.remove(myTermText);
                           TreeMap freq = new TreeMap();
                           freq = myTerm.frequency; // on recupère les occurences dans les autre documents
                                    
                           if (freq.containsKey(count_id_doc)) { // si le terme a déjà été trouvé pour le document
    
                                   TermFrequency myTermFrequency = (TermFrequency) freq.get(count_id_doc);
                                   freq.remove(count_id_doc);
                                    myTermFrequency.frequency++;
                                   freq.put(count_id_doc, myTermFrequency);
                                   Term myNewTerm = new Term(myTerm.term_id, myTerm.text, freq, myTerm.positionDoc);
                                   
                                   myNewTerm.addPositionDoc(iddoc, myTerm.term_id, term_count , idbalise);//On ajoute sa position et sa balise
                                   postingTable.put(myTermText, myNewTerm);       
                           }      
                             
                           else { // si le terme est trouve dans un nouvel docuemnt
                            		short un =1;
                                	TermFrequency myTermFrequency = new TermFrequency(count_id_doc,un);   
                                 	freq.put(count_id_doc, myTermFrequency);
                                	                                 
                                 	Term myNewTerm = new Term(myTerm.term_id, myTerm.text, freq, myTerm.positionDoc);
                                 	
                                 	myNewTerm.addPositionDoc(iddoc, myTerm.term_id, term_count , idbalise);//On ajoute sa position et sa balise
                                 	postingTable.put(myTermText, myNewTerm); 
                                 	Boolean myNewBoolean = new Boolean(false);             
                                 	
		 					}
                          
                 		} //if postinTable.containsKey
                     	else { // si la table de posting ne contient pas le terme, on l'insere!
                                                                                                     
                                short un=1;
                                TermFrequency myTermFrequency = new TermFrequency(count_id_doc,un );
                       
                                TreeMap freq = new TreeMap();
                                freq.put(count_id_doc, myTermFrequency);
                                Term myTerm = new Term(count_id_term, mot, freq);
                                
                                myTerm.addPositionDoc(iddoc, count_id_term, term_count, idbalise);//On insère sa position
                                
                                count_id_term++;
                                postingTable.put(myTermText, myTerm);
                                
                               
                            
                     } //else  

	}	// if

} // for


}



/** Prints the documentVector */
   public final void PrintDocumentTable() {
          
      for (Enumeration e=documentVector.elements(); e.hasMoreElements(); ) {
                DocumentAIndexer tempDocument=new DocumentAIndexer();
                tempDocument= (DocumentAIndexer) e.nextElement();
                tempDocument.PrintDocument();
           }    
          
          
  } // PrintDocumentTable()
  
  
 
  
  
  

   
   /** Prints the postingTable*/
   public final void PrintPostingTable() {
          
    for (Enumeration e=postingTable.elements(); e.hasMoreElements(); ) {
                Term tempTerm=new Term();
                tempTerm= (Term) e.nextElement();
                tempTerm.PrintTerm();
           }         
       
  }  // PrintPostingTable()
   
   
   
   
   
} //IndexWriter.java


